package com.vieewer.btdemo.view.microsoft.translate

import android.content.Context
import android.util.Log
import android.widget.Toast
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.lindroid.androidutilskt.extension.getSpString
import com.vieewer.btdemo.bean.DrawTextBean
import com.vieewer.btdemo.bean.OCRResultBean
import com.vieewer.btdemo.bean.TranslateBean
import com.vieewer.btdemo.showLoading
import com.vieewer.btdemo.utils.CommonUtils
import com.vieewer.btdemo.utils.LogUtil
import com.vieewer.btdemo.view.microsoft.audio.TranslateHelper
import org.apache.http.client.methods.HttpPost
import org.apache.http.client.utils.URIBuilder
import org.apache.http.entity.InputStreamEntity
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.util.EntityUtils
import org.json.JSONObject
import java.io.FileInputStream
import java.lang.StringBuilder

class TranslateTools  private constructor() {

    var mContext : Context ? = null
    private lateinit var mHttpClient : CloseableHttpClient
    private val endpoint = "https://vieewerocr.cognitiveservices.azure.com/"
    private val uriBase = endpoint + "vision/v2.1/ocr"
    private val subscriptionKey = "28db17501a2847419c59c7ffb6073d1a"


    var mIndex = 0
    var mDrawTextDatas =  ArrayList<DrawTextBean>()
    var mIsFinish = false
    private var mHandler : TranslateImgActivity.MyHandler ? = null


    private object InstanceHolder {
        val holder = TranslateTools()
    }

    fun init (ctx : Context) {
        mContext = ctx
        mHttpClient = HttpClientBuilder.create().build()
    }

    fun setHandler(handler : TranslateImgActivity.MyHandler) {
        mHandler = handler
    }


    companion object {
        val instance = InstanceHolder.holder
    }

     fun recognizeOcrAndTranslate(photoFile : String) {

        mContext!!.showLoading()

        Thread {

            try {
                val uriBuilder = URIBuilder(uriBase)

                val fromLanguage = CommonUtils.getformatedCode(getSpString("SP_KEY_ORIGIN_LANGUAGE", "en"))

                Log.i("yjj", "ocr翻译：起始语言$fromLanguage")

                uriBuilder.setParameter("language", fromLanguage)//unk zh-Hans
                uriBuilder.setParameter("detectOrientation", "true")


                // Request parameters.
                val uri = uriBuilder.build()
                val request = HttpPost(uri)

                // Request headers.
                request.setHeader("Content-Type", "application/octet-stream")
                request.setHeader("Ocp-Apim-Subscription-Key", subscriptionKey)



                /*   val file = File(
                       getExternalStorageDirectory().getAbsolutePath(),
                       "/tencent/QQfile_recv/img_democritus.png"
                   )*/

                val reqEntity = InputStreamEntity(
                    FileInputStream(photoFile), -1
                )

                reqEntity.setChunked(true) // Send in multiple parts if needed
                request.entity = reqEntity


                // Request body.
                //val requestEntity = StringEntity("{\"url\":\"$imageToAnalyze\"}")
                //request.setEntity(requestEntity)


                // Call the REST API method and get the response entity.
                val response = mHttpClient.execute(request)
                val entity = response.entity

                if (entity != null) {
                    // Format and display the JSON response.
                    val jsonString = EntityUtils.toString(entity)
                    val json = JSONObject(jsonString)


                    var resultBean : OCRResultBean = Gson().fromJson(jsonString, OCRResultBean::class.java)
                    mIndex = 0
                    if (resultBean.orientation == "NotDetected" || resultBean.regions.size == 0) {
                        Toast.makeText(mContext, "ocr未识别出结果，请检查翻译语言是否已经设置，并重新拍照", Toast.LENGTH_SHORT).show()
                    } else {
                        tearApartToLineWords(resultBean)
                    }



                    LogUtil.e("yjj", "REST Ocr Response:\n" + json.toString(2))
                }
            } catch (e: Exception) {
                // Display error message.
                Log.i("translate error", e.toString())
                if (e.toString().contains("java.net.UnknownHostException")) {
                    showNetErrorToast()
                }
                //mContext!!.dismiss()
                dismissDialog()
            }


        }.start()

    }

    private fun showNetErrorToast() {
        val msg = mHandler!!.obtainMessage()
        msg.what = 3
        mHandler!!.sendMessage(msg)
    }

    private fun dismissDialog() {
        val msg = mHandler!!.obtainMessage()
        msg.what = 2
        mHandler!!.sendMessage(msg)
    }


    private fun tearApartToLineWords(data : OCRResultBean) {
        if (data != null) {

            mDrawTextDatas.clear()

            for (i in 0 until data.getRegions().size) {

                val regionsBean = data.getRegions().get(i)

                for (j in 0 until regionsBean.getLines().size) {

                    val boundingBox = regionsBean.getLines().get(j).getBoundingBox()
                    val indexs = boundingBox.split(",".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()
                    val x = java.lang.Float.parseFloat(indexs[0])
                    val y = java.lang.Float.parseFloat(indexs[1])
                    Log.i("yjj", "ondraw x = $x, y =$y")

                    val wordsList = regionsBean.getLines().get(j).getWords()
                    var words = ""
                    val sb = StringBuilder()
                    for (k in wordsList.indices) {
                        sb.append(wordsList.get(k).getText() + " ")
                    }

                    words = sb.toString()

                    mIsFinish = true

                    var drawTextBean = DrawTextBean()
                    drawTextBean.x = x
                    drawTextBean.y = y
                    drawTextBean.lineWords = words
                    //var curBean = translateLineWords(words, x , y)
                    mDrawTextDatas.add(drawTextBean)


                    Log.i("yjj", "ondraw words =  $words")

                }

            }

            operate(mIndex)


        }
    }



    private fun operate(pos: Int) {
        Log.i("yjj", "operate >>>> pos =$pos")
        var lineWords = translate(mDrawTextDatas[pos].lineWords, pos)

        if ((pos + 1) == mDrawTextDatas.size) {
            refreshUIView()
        }
    }


    private fun refreshTxtContent() {
        //mContext!!.dismiss()
        dismissDialog()

        val msg = mHandler!!.obtainMessage()
        msg.what = 1
        msg.obj = mDrawTextDatas
        mHandler!!.sendMessage(msg)

    }


    private fun refreshUIView() {
        if (mDrawTextDatas != null && mDrawTextDatas!!.size > 0) {
            refreshTxtContent()
        }
    }



    fun translate(content : String, index :Int) : String {

        Log.i("yjj", "translate >>>")

        // Android 4.0 之后不能在主线程中请求HTTP请求
        var resultString = ""
        Thread {
            try {
                //todo split and trans zh-hans
                val targetLanguage = CommonUtils.getformatedCode(getSpString("SP_KEY_TARGET_LANGUAGE", "zh-Hans"))
                Log.i("yjj", "ocr翻译：目标语言" + targetLanguage)
                val translateRequest = TranslateHelper()
                translateRequest.setLanguageCode(targetLanguage)
                val content = "[{\n\t\"Text\": \"" + content + "\"\n}]"
                val response = translateRequest.Post(content)
                val result = TranslateHelper.prettify(response)
                Log.i("yjj", result)
                var list = Gson().fromJson<List<TranslateBean>>(result, object : TypeToken<List<TranslateBean>>() {

                }.type)

                if (list != null && list.size > 0) {
                    resultString  = list!!.get(0).getTranslations().get(0).getText()
                    Log.i("yjj", " ocr translate result :" + resultString)
                    mDrawTextDatas[index].lineWords = resultString
                }

                if ((index + 1) < mDrawTextDatas.size) {
                    operate(++mIndex)
                }


            } catch (e: Exception) {
                Log.i("yjj", e.toString())
                //mContext!!.dismiss()
                dismissDialog()
            }


        }.start()

        return resultString
    }




}